For documentation and information about some of the methods employed in Brent's demo, see Creating Dialogs by API
'**********************************************************************
' Container Control Demo
' By Brent D. Thorn, Nov. 2004
' This code is released to the public domain.
' No credit to the author is necessary.
'**********************************************************************
If Val(Version$) < 4 Then
Notice "Code requires LB 4.0 or later."
End
End If
Global ghContainer ' HWND of container.
NoMainWin
WindowWidth = 350
WindowHeight = 350
UpperLeftX = (DisplayWidth - WindowWidth) / 2
UpperLeftY = (DisplayHeight - WindowHeight) / 2
Button #p.btn1, "Show Container", ShowHide, UL, 10, 20
Checkbox #p.chk1, "Checkbox", Handler1, Handler1, 10, 10, 100, 20
RadioButton #p.opt1, "Top", ToTop, Handler1, 10, 30, 100, 20
RadioButton #p.opt2, "Middle", ToMid, Handler1, 10, 50, 100, 20
RadioButton #p.opt3, "Bottom", ToBot, Handler1, 10, 70, 100, 20
Open "Container Demo" For Window As #p
#p "TrapClose Quit"
#p.opt1 "Set"
' Create a hidden container 150x150 in size.
hInstance = GetWindowLong(HWnd(#p), _GWL_HINSTANCE)
ghContainer = CreateContainer(0, 0, 150, 0, 150, 150, HWnd(#p), hInstance, 0)
' Have container "adopt" controls.
Call SetParent HWnd(#p.chk1), ghContainer
Call SetParent HWnd(#p.opt1), ghContainer
Call SetParent HWnd(#p.opt2), ghContainer
Call SetParent HWnd(#p.opt3), ghContainer
Call DoEvents
Sub DoEvents
[localLoop]
Scan
CallDLL #kernel32, "Sleep", 50 As Long, r As void
GoTo [localLoop]
End Sub
Sub ShowHide Handle$
CallDLL #user32, "IsWindowVisible", ghContainer As ULong,_
itis As Long
If itis Then
cmd = _SW_HIDE
#Handle$ "Show Container"
Else
cmd = _SW_SHOW
#Handle$ "Hide Container"
End If
CallDLL #user32, "ShowWindow", ghContainer As ULong,_
cmd As Long, r As Long
End Sub
Sub ToTop Handle$
Call MoveWindow ghContainer, 150, 0
End Sub
Sub ToMid Handle$
Call MoveWindow ghContainer, 150, 100
End Sub
Sub ToBot Handle$
Call MoveWindow ghContainer, 150, 200
End Sub
Sub Quit Handle$
Close #Handle$
End
End Sub
Sub Handler1 Handle$
End Sub
'**********************************************************************
' Container Management
'**********************************************************************
Function CreateContainer( ExStyle, Style, X, Y, Width, Height, hParent, hInstance, lParam )
'-- Purpose: Creates a child dialog box for use as a container object
' for controls. Controls must be "adopted" using SetParent.
'-- Returns: Window handle (HWND) of the newly-created container.
'-- Depends: ContainerProc(), HIWORD(), LOWORD(), MulDiv()
' Get dialog base units.
' They're used to convert pixels to dialog units.
CallDLL #user32, "GetDialogBaseUnits", r As ULong
baseX = LOWORD(r)
baseY = HIWORD(r)
' Initialize dialog template struct.
Struct DLGTEMPLATE, _
style As ULong, _
dwExtendedStyle As ULong, _
cdit As Word, _
x As Short, _
y As Short, _
cx As Short, _
cy As Short, _
menus As Word, _ 'pseudo element
class As Word, _ 'pseudo element
title As Word 'pseudo element
DLGTEMPLATE.style.struct = Style Or _WS_CHILDWINDOW Or _DS_CONTROL
DLGTEMPLATE.dwExtendedStyle.struct = ExStyle Or _WS_EX_CONTROLPARENT
DLGTEMPLATE.cdit.struct = 0
DLGTEMPLATE.x.struct = MulDiv(X, 4, baseX)
DLGTEMPLATE.y.struct = MulDiv(Y, 8, baseY)
DLGTEMPLATE.cx.struct = MulDiv(Width, 4, baseX)
DLGTEMPLATE.cy.struct = MulDiv(Height, 8, baseY)
DLGTEMPLATE.menus.struct = 0
DLGTEMPLATE.class.struct = 0
DLGTEMPLATE.title.struct = 0
' Template must be in global memory space.
cbDT = Len(DLGTEMPLATE.struct)
CallDLL #kernel32, "GlobalAlloc", _GMEM_MOVEABLE As ULong,_
cbDT As ULong, hDT As ULong
CallDLL #kernel32, "GlobalLock", hDT As ULong, pDT As ULong
' Copy struct to global memory.
CallDLL #kernel32, "RtlMoveMemory", pDT As ULong, DLGTEMPLATE As Struct,_
cbDT As Long, r As void
' Get pointer to ContainerProc().
Callback lpDlgProc, ContainerProc( ULong, ULong, ULong, ULong ), ULong
' Create the modeless, child dialog box.
CallDLL #user32, "CreateDialogIndirectParamA", hInstance As Long,_
pDT As ULong, hParent As ULong, lpDlgProc As ULong, lParam As Long,_
hDlg As ULong
' Memory is no longer needed. Let's clean up.
CallDLL #kernel32, "GlobalUnlock", hDT As ULong, r As Long
CallDLL #kernel32, "GlobalFree", hDT As ULong, r As ULong
' Return dialog's window handle.
CreateContainer = hDlg
End Function
Function ContainerProc( hDlg, uMsg, wParam, lParam )
'-- Purpose: Acts as container dialog box's dialog procedure (DLGPROC).
' Forwards WM_COMMAND and WM_NOTIFY messages to the container's
' parent window.
Select Case uMsg
Case _WM_COMMAND, _WM_NOTIFY
CallDLL #user32, "GetParent", hDlg As ULong, hParent As Ulong
CallDLL #user32, "SendMessageA", hParent As ULong,_
uMsg As ULong, wParam As ULong, lParam As ULong, r As Long
End Select
End Function
'***********************************************
' Support Procedures
'***********************************************
Function HIWORD( dw )
HIWORD = (dw And 4294901760) / 65536
End Function
Function LOWORD( dw )
LOWORD = (dw And 65535)
End Function
Function GetWindowLong( hWnd, Index )
CallDLL #user32, "GetWindowLongA",_
hWnd As ULong, Index As Long,_
GetWindowLong As Long
End Function
Function MulDiv( Number, Numerator, Denominator )
CallDLL #kernel32, "MulDiv", Number As Long,_
Numerator As Long, Denominator As Long,_
MulDiv As Long
End Function
Sub MoveWindow hWnd, X, Y
flags = _SWP_NOZORDER Or _SWP_NOSIZE
CallDLL #user32, "SetWindowPos", hWnd As ULong,_
_NULL As ULong, X As Long, Y As Long, 0 As Long,_
0 As Long, flags As Long, r As Long
End Sub
Sub SetParent hWnd, hNewParent
CallDLL #user32, "SetParent", hWnd As ULong,_
hNewParent As ULong, r As ULong
End Sub